////////////////////////////////////////////////////////////////////////////////
//
//  ADOBE SYSTEMS INCORPORATED
//  Copyright 2008 Adobe Systems Incorporated
//  All Rights Reserved.
//
//  NOTICE: Adobe permits you to use, modify, and distribute this file
//  in accordance with the terms of the license agreement accompanying it.
//
////////////////////////////////////////////////////////////////////////////////


package coco.component
{
	
	import flash.events.KeyboardEvent;
	
	import mx.core.UIComponentGlobals;
	import mx.core.mx_internal;
	
	import spark.components.TextInput;
	import spark.components.supportClasses.DropDownListBase;
	import spark.components.supportClasses.TextBase;
	import spark.utils.LabelUtil;
	
	use namespace mx_internal;
	
	public class CocoDropDownList extends DropDownListBase
	{
		//--------------------------------------------------------------------------
		//
		//  Constructor
		//
		//--------------------------------------------------------------------------
		
		/**
		 *  Constructor. 
		 *  
		 *  @langversion 3.0
		 *  @playerversion Flash 10
		 *  @playerversion AIR 1.5
		 *  @productversion Flex 4
		 */
		public function CocoDropDownList()
		{
			super();
		}
		
		//--------------------------------------------------------------------------
		//
		//  Skin parts
		//
		//--------------------------------------------------------------------------    
		
		//----------------------------------
		//  labelDisplay
		//----------------------------------
		
		[SkinPart(required="false")]
		
		/**
		 *  An optional skin part that holds the prompt or the text of the selected item. 
		 *  
		 *  @langversion 3.0
		 *  @playerversion Flash 10
		 *  @playerversion AIR 1.5
		 *  @productversion Flex 4
		 */
		public var labelDisplay:TextInput;
		
		//--------------------------------------------------------------------------
		//
		//  Variables
		//
		//--------------------------------------------------------------------------
		
		private var labelChanged:Boolean = false;
		private var labelDisplayExplicitWidth:Number; 
		private var labelDisplayExplicitHeight:Number; 
		private var sizeSetByTypicalItem:Boolean;
		
		//--------------------------------------------------------------------------
		//
		//  Overridden properties
		//
		//--------------------------------------------------------------------------
		
		//----------------------------------
		//  baselinePosition
		//----------------------------------
		
		/**
		 *  @private
		 */
		override public function get baselinePosition():Number
		{
			return getBaselinePositionForPart(labelDisplay);
		}
		
		//--------------------------------------------------------------------------
		//
		//  Properties
		//
		//--------------------------------------------------------------------------
		
		//----------------------------------
		//  prompt
		//----------------------------------
		
		/**
		 *  @private
		 */
		private var _prompt:String = "";
		
		/**
		 *  The prompt for the DropDownList control. 
		 *  The prompt is a String that is displayed in the
		 *  DropDownList when <code>selectedIndex</code> = -1.  
		 *  It is usually a String such as "Select one...". 
		 *  Selecting an item in the drop-down list replaces the 
		 *  prompt with the text from the selected item.
		 *  
		 *  @default ""
		 *       
		 *  @langversion 3.0
		 *  @playerversion Flash 10
		 *  @playerversion AIR 1.5
		 *  @productversion Flex 4
		 */
		public function get prompt():String
		{
			return _prompt;
		}
		
		/**
		 *  @private
		 */
		public function set prompt(value:String):void
		{
			if (_prompt == value)
				return;
			
			_prompt = value;
			labelChanged = true;
			invalidateProperties();
		}
		
		//--------------------------------------------------------------------------
		//
		//  Overridden Properties
		//
		//--------------------------------------------------------------------------
		
		/**
		 *  Layouts use the preferred size of the <code>typicalItem</code>
		 *  when fixed row or column sizes are required, but a specific 
		 *  <code>rowHeight</code> or <code>columnWidth</code> value is not set.
		 *  Similarly virtual layouts use this item to define the size 
		 *  of layout elements that have not been scrolled into view.
		 *
		 *  <p>The container  uses the typical data item, and the associated item renderer, 
		 *  to determine the default size of the container children. 
		 *  By defining the typical item, the container does not have to size each child 
		 *  as it is drawn on the screen.</p>
		 *
		 *  <p>Setting this property sets the <code>typicalLayoutElement</code> property
		 *  of the layout.</p>
		 * 
		 *  <p>Restriction: if the <code>typicalItem</code> is an IVisualItem, it must not 
		 *  also be a member of the data provider.</p>
		 * 
		 *  <p>Note: Setting <code>typicalItem</code> overrides any explicit width or height
		 *  set on the <code>labelDisplay</code> skin part. </p>
		 * 
		 *  @default null
		 *  
		 *  @langversion 3.0
		 *  @playerversion Flash 10
		 *  @playerversion AIR 1.5
		 *  @productversion Flex 4
		 */
		override public function set typicalItem(value:Object):void
		{
			super.typicalItem = value;
			invalidateSize();
		}
		
		//--------------------------------------------------------------------------
		//
		//  Overridden methods
		//
		//--------------------------------------------------------------------------
		
		/**
		 *  @private
		 */ 
		override protected function commitProperties():void
		{
			super.commitProperties();
			
			if (labelChanged)
			{
				labelChanged = false;
				updateLabelDisplay();
			}
		}
		
		/**
		 *  @private
		 */ 
		override protected function partAdded(partName:String, instance:Object):void
		{
			super.partAdded(partName, instance);
			
			if (instance == labelDisplay)
			{
				labelChanged = true;
				invalidateProperties();
			}
		}
		
		/**
		 *  @private
		 */
		override protected function measure():void
		{
			// If typicalItem is set, then use it for measurement
			if (labelDisplay && typicalItem != null)
			{   
				// Save the labelDisplay's dimensions in case we clear out typicalItem
				if (!sizeSetByTypicalItem)
				{
					labelDisplayExplicitWidth = labelDisplay.explicitWidth;
					labelDisplayExplicitHeight = labelDisplay.explicitHeight;
					sizeSetByTypicalItem = true;
				}
				
				labelDisplay.explicitWidth = NaN;
				labelDisplay.explicitHeight = NaN;
				
				// Swap in the typicalItem into the labelDisplay
				updateLabelDisplay(typicalItem);
				UIComponentGlobals.layoutManager.validateClient(skin, true);
				
				// Force the labelDisplay to be sized to the measured size
				labelDisplay.width = labelDisplay.measuredWidth;
				labelDisplay.height = labelDisplay.measuredHeight;
				
				// Set the labelDisplay back to selectedItem
				updateLabelDisplay();
			}
			else if (sizeSetByTypicalItem && typicalItem == null)
			{
				// Restore the labelDisplay to its original size
				labelDisplay.width = labelDisplayExplicitWidth;
				labelDisplay.height = labelDisplayExplicitHeight;
				sizeSetByTypicalItem = false;
			}
			
			super.measure();
		}
		
		/**
		 *  @private
		 *  Called whenever we need to update the text passed to the labelDisplay skin part
		 */
		// TODO (jszeto): Make this protected and make the name more generic (passing data to skin) 
		override mx_internal function updateLabelDisplay(displayItem:* = undefined):void
		{
			if (labelDisplay)
			{
				if (displayItem == undefined)
					displayItem = selectedItem;
				if (displayItem != null && displayItem != undefined)
					labelDisplay.text = LabelUtil.itemToLabel(displayItem, labelField, labelFunction);
				else
					labelDisplay.text = prompt;
			}   
		}
		
		override protected function keyDownHandler(event:KeyboardEvent):void
		{
			selectedIndex = -1;
		}
		
	}
	
}
